using System;
using MonoTouch.UIKit;
using GameOfLifeX.Core;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Drawing;
using MonoTouch.Dialog;

namespace GameOfLifeX.IOS.NewModelTest
{
	public class MyViewController : UIViewController
	{
		private readonly int _width;
		private readonly int _height;
		private GameOfLifeModel _model;
		private ModelState _modelState = ModelState.Running;
		private Preferences _preferences;
		private BindingContext _bindingContext;
		private UINavigationController _preferencesNavigationController;
		private int _delay;

		public MyViewController (int width, int height)
		{
			_width = width;
			_height = height;
			InitializeModelAndStartTimer ();
		}

		public override void LoadView ()
		{
			_preferences = new Preferences ();
			_bindingContext = new BindingContext (this, _preferences, "Preferences");
			_preferencesNavigationController = new UINavigationController (new DialogViewController (_bindingContext.Root));
			_delay = (int)Decimal.Round (Convert.ToDecimal (_preferences.SimulationSpeed));

			base.LoadView ();
			View = new MyImageView (_width, _height){ RenderingMode = _preferences.RenderingMode };

			var button = UIButton.FromType (UIButtonType.RoundedRect);
			button.Frame = new RectangleF (0, 0, 100, 100);
			button.SetTitle ("Ninja", UIControlState.Normal);
			button.SetTitleColor (UIColor.White, UIControlState.Normal);
			button.TouchUpInside += (object sender, EventArgs e) => ShowOptions ();
			View.Add (button);
		}

		private void ShowOptions ()
		{
			_modelState = ModelState.Paused;
			PresentViewController (_preferencesNavigationController, false, null);
		}

		public void CloseOptions ()
		{
			_modelState = ModelState.Running;
			_bindingContext.Fetch ();
			_preferencesNavigationController.DismissViewController (false, null);
			((MyImageView)View).RenderingMode = _preferences.RenderingMode;
			_delay = (int)Decimal.Round (Convert.ToDecimal (_preferences.SimulationSpeed));
			StartTimer ();
		}

		public void ClearModel ()
		{
			_model.Clear ();
		}

		private void InitializeModelAndStartTimer ()
		{
			_model = new GameOfLifeModel (_width, _height);
			_model.SeedRandomly ();
			StartTimer ();
		}

		private async void StartTimer ()
		{
			while (_modelState == ModelState.Running)
			{
				GameLoopTick ();
				await Task.Delay (_delay);
			}
		}

		private int _loopCounter = 0;
		private readonly Stopwatch sw = Stopwatch.StartNew ();
		private const int _measureFrequency = 20;

		void GameLoopTick ()
		{
			_loopCounter++;
			if (_loopCounter % _measureFrequency == 0)
			{
				Console.WriteLine ("FPS: " + _measureFrequency / sw.Elapsed.TotalSeconds);
				sw.Restart ();
			}

			var lastTopuch = ((MyImageView)View).LastTouch;
			if (lastTopuch != null)
			{
				((MyImageView)View).LastTouch = null;
				var location = lastTopuch.LocationInView (View);
				if (Math.Round (location.X) != 0)
				{
					var bounds = View.Bounds;
					_model.GenerateCellsAtTouchLocation (bounds.Width, bounds.Height, location.X, location.Y);
				}
			}

			_model.RunGeneration ();
			((MyImageView)View).RenderCells (_model.GetGrid ());
		}
	}
}

